package cool.xiaokang.familyaccount.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.serializer.PropertyFilter;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cool.xiaokang.familyaccount.pojo.InAccount;
import cool.xiaokang.familyaccount.pojo.InAccountType;
import cool.xiaokang.familyaccount.pojo.User;
import cool.xiaokang.familyaccount.service.InAccountService;
import cool.xiaokang.familyaccount.service.InAccountTypeService;
import cool.xiaokang.familyaccount.service.UserService;
import cool.xiaokang.familyaccount.utils.FileUtils;
import cool.xiaokang.familyaccount.utils.ResponseUtils;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Controller
@Scope("prototype")
public class InAccountAction extends ActionSupport implements ModelDriven<InAccount> {
	private static final long serialVersionUID = 4432188950314390015L;

	@Autowired
	private InAccountService inAccountService;

	@Autowired
	private InAccountTypeService inAccountTypeService;

	@Autowired
	private UserService userService;

	private Date startTime;
	private Date endTime;
	private String desc;
	private String year;
	private InAccount inAccount = new InAccount();
	private File myFile;

	public String getStartTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(startTime);
	}

	public String getEndTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(endTime);
	}

	// 为首页准备6条收入账单（收入金额降序）
	public String findSixInAccount() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<InAccount> findSixInAccount = inAccountService.findSixInAccount(user.getUser_id());
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respListRef(ServletActionContext.getResponse(), findSixInAccount, filter);
		return NONE;
	}

	// 进入收入账单jsp
	public String list() throws Exception {
		return "toList";
	}

	// 当前用户的收入账单（收入时间降序）
	public String listCurrentUser() throws Exception {
		DetachedCriteria dc = DetachedCriteria.forClass(InAccount.class);
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		dc.add(Restrictions.eq("user.user_id", user.getUser_id()));
		dc.addOrder(Order.desc("inaccount_datetime"));
		if (startTime != null || endTime != null) {
			if (startTime != null && endTime != null) {
				dc.add(Restrictions.between("inaccount_datetime", startTime, endTime));
			} else {
				dc.add(Restrictions.like("inaccount_datetime", startTime != null ? startTime : endTime));
			}
		}
		if (StringUtils.isNotBlank(desc)) {
			inAccount.setInaccount_desc(desc);
			dc.add(Restrictions.like("inaccount_desc", "%" + inAccount.getInaccount_desc() + "%"));
		}
		List<InAccount> inAccounts = inAccountService.findList(dc);
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respListRef(ServletActionContext.getResponse(), inAccounts, filter);
		return NONE;
	}

	/**
	 * 添加账单
	 * 
	 * @return
	 * @throws Exception
	 */
	public String add() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		inAccount.setUser(user);
		InAccountType inAccountType = inAccountTypeService.findById(inAccount.getInAccountType().getInaccounttype_id());
		inAccount.setInAccountType(inAccountType);
		inAccount.setInaccount_createtime(new Date());
		inAccountService.save(inAccount);
		return "toShow";
	}

	/**
	 * 上传收入账单
	 * 
	 * @throws IOException
	 * @throws ParseException
	 * @throws Exception
	 */
	public String upload() throws IOException {
		HSSFWorkbook workbook;
		String flag = "1";
		try {
			workbook = new HSSFWorkbook(new FileInputStream(myFile));
			HSSFSheet sheet = workbook.getSheetAt(0);
			List<InAccount> list = new ArrayList<InAccount>();
			User user = (User) ActionContext.getContext().getSession().get("currentUser");
			for (Row row : sheet) {
				if (row.getRowNum() == 0 || row.getRowNum() == 1) {
					continue;
				}
				String typename = row.getCell(0).getStringCellValue();
				String inaccount_money = "";
				if (row.getCell(1) != null) {
					row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
					inaccount_money = row.getCell(1).getStringCellValue();
				}
				String inaccount_datatimeStr = "";
				if (row.getCell(2) != null) {
					row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
					inaccount_datatimeStr = row.getCell(2).getStringCellValue();
				}
				String inaccount_desc = row.getCell(3).getStringCellValue();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				Date inaccount_datatime = sdf.parse(inaccount_datatimeStr);
				InAccount inAccount = new InAccount(inaccount_datatime, Double.valueOf(inaccount_money), new Date(),
						inaccount_desc);
				InAccountType inAccountType = new InAccountType();
				inAccountType.setInaccounttype_name(typename);
				inAccount.setInAccountType(inAccountType);
				inAccount.setUser(user);
				list.add(inAccount);
			}
			inAccountService.saveInAccount(list, user.getUser_id());
		} catch (Exception e) {
			flag = "0";
			e.printStackTrace();
		}
		ServletActionContext.getResponse().getWriter().write(flag);
		return NONE;
	}

	/**
	 * 下载收入账单
	 */
	@SuppressWarnings({ "resource", "deprecation" })
	public String download() throws IOException {
		DetachedCriteria dc = DetachedCriteria.forClass(InAccount.class);
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		dc.add(Restrictions.eq("user.user_id", user.getUser_id()));
		dc.addOrder(Order.asc("inaccount_datetime"));
		List<InAccount> list = inAccountService.findList(dc);
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("收入账单");
		sheet.setDefaultColumnWidth(20);// 默认宽度

		// 第一行蓝色宋体加粗
		HSSFCellStyle cellStyle1 = workbook.createCellStyle();
		cellStyle1.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
		HSSFFont fontStyle1 = workbook.createFont();
		fontStyle1.setFontName("宋体"); // 字体样式
		fontStyle1.setColor(HSSFColor.BLUE.index);
		fontStyle1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
		fontStyle1.setFontHeightInPoints((short) 14);// 字体大小
		cellStyle1.setFont(fontStyle1);

		HSSFCellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
		HSSFFont fontStyle = workbook.createFont();
		fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
		fontStyle.setFontHeightInPoints((short) 11);// 字体大小
		cellStyle.setFont(fontStyle);

		// 创建一行
		HSSFRow row = sheet.createRow(0);
		HSSFCell createCell = row.createCell(0);
		createCell.setCellValue("用户【" + user.getUser_name() + "】-收入账单");
		createCell.setCellStyle(cellStyle1);
		sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));
		// 设置头信息
		HSSFRow row2 = sheet.createRow(1);
		HSSFCell cell = row2.createCell(0);
		cell.setCellValue("收入类型");
		cell.setCellStyle(cellStyle);
		HSSFCell cell2 = row2.createCell(1);
		cell2.setCellValue("收入金额");
		cell2.setCellStyle(cellStyle);
		HSSFCell cell3 = row2.createCell(2);
		cell3.setCellValue("收入日期");
		cell3.setCellStyle(cellStyle);
		HSSFCell cell4 = row2.createCell(3);
		cell4.setCellValue("备注");
		cell4.setCellStyle(cellStyle);
		for (InAccount inAccount1 : list) {
			HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
			dataRow.createCell(0).setCellValue(inAccount1.getInAccountType().getInaccounttype_name());
			dataRow.createCell(1).setCellValue(inAccount1.getInaccount_money());
			dataRow.createCell(2).setCellValue(inAccount1.getInaccount_datetime_s());
			dataRow.createCell(3).setCellValue(inAccount1.getInaccount_desc());
		}
		// 下载
		String filename = "用户" + user.getUser_name() + "_收入账单_" + System.currentTimeMillis() + ".xls";
		String contentType = ServletActionContext.getServletContext().getMimeType(filename);
		ServletOutputStream stream = ServletActionContext.getResponse().getOutputStream();
		ServletActionContext.getResponse().setContentType(contentType);
		String agent = ServletActionContext.getRequest().getHeader("User-Agent");
		filename = FileUtils.encodeDownloadFilename(filename, agent);
		ServletActionContext.getResponse().setHeader("content-disposition", "attachment;filename=" + filename);
		workbook.write(stream);
		return NONE;
	}

	/**
	 * 根据ID删除收入账单
	 * 
	 * @return
	 */
	public String delete() {
		String flag = "1";
		try {
			inAccountService.deleteById(inAccount.getInaccount_id());
		} catch (Exception e) {
			flag = "0";
			e.printStackTrace();
		}
		return "toShow";
	}

	// 用来回显修改
	public String findById() throws Exception {
		InAccount inaccount = inAccountService.findById(inAccount.getInaccount_id());
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("inaccounts")) {
					flag = false;
				} else if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respObjAndFilter(ServletActionContext.getResponse(), inaccount, filter);
		return NONE;
	}

	// 修改收入账单
	public String update() {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		inAccount.setUser(user);
		InAccountType intype = inAccountTypeService.findById(inAccount.getInAccountType().getInaccounttype_id());
		inAccount.setInAccountType(intype);
		inAccount.setInaccount_createtime(new Date());
		inAccountService.update(inAccount);
		return "toShow";
	}

	// 根据账单类型分类查询出当年或某年的收入账单总和
	public String findInAccountGroupByInAccountTypeName() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<Object> list = inAccountService.findInAccountGroupByInAccountTypeName(user.getUser_id(), year);
		ResponseUtils.respObj(ServletActionContext.getResponse(), list);
		return NONE;
	}

	// 根据账单类型分类查询出当年或某年中各个月的收入账单总和
	public String findInAccountWithYearly() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<Object> yearly = new ArrayList<Object>(0);
		List<Object> perYearList = inAccountService.findInAccountGroupByInAccountTypeName(user.getUser_id(), year);
		List<Object> perMonthList = inAccountService.findInAccountWithYearly(user.getUser_id(), year);
		List<Object> perMonthAvgMoney = inAccountService.findPerMonthAvgMoney(user.getUser_id(), year);
		yearly.add(perYearList);
		yearly.add(perMonthList);
		yearly.add(perMonthAvgMoney);
		// System.out.println(JSON.toJSONString(yearly));
		ResponseUtils.respObj(ServletActionContext.getResponse(), yearly);
		return NONE;
	}

	@Override
	public InAccount getModel() {
		return inAccount;
	}

}
